﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Net.Http;
using System.Security.Claims;
using TomNet.App.Model.DB.Identity;
using TomNet.App.Model.DTO;
using TomNet.App.WebApi.Common;
using TomNet.AspNetCore.Data;
using TomNet.AspNetCore.Mvc;
using TomNet.Authentication.JwtBearer;
using TomNet.Caching;
using TomNet.Core;
using TomNet.Core.Options;
using TomNet.Data;
using TomNet.Extensions;
using TomNet.Security;
using TomNet.SqlSugarCore.Entity;

namespace TomNet.App.WebApi.Controllers
{
    [Authorize]
    public class AccountController : ApiController
    {
        private readonly IUnitOfWork _unitOfWork;
        private IDistributedCache _cache;
        private IHttpClientFactory _httpClientFactory;
        public AccountController(IUnitOfWork unitOfWork, IServiceProvider provider, IHttpClientFactory httpClientFactory)
        {
            _unitOfWork = unitOfWork;
            _cache = provider.GetService<IDistributedCache>();
            _httpClientFactory = httpClientFactory;
        }
        /// <summary>
        /// Jwt登录
        /// </summary>
        /// <returns>JSON操作结果</returns>
        [AllowAnonymous]
        [HttpPost]
        public AjaxResult Login(LoginDto dto)
        {
            Check.NotNull(dto, nameof(dto));

            if (!ModelState.IsValid)
            {
                return new AjaxResult("提交信息验证失败", AjaxResultType.Error);
            }

            var user = _unitOfWork.DbContext.Queryable<UserLogin>().First(m => m.UserName == dto.UserName && m.Password == dto.Password);

            if (user == null)
            {
                return new AjaxResult("账户或密码错误", AjaxResultType.Error);
            }
            //生成Token，这里只包含最基本信息，其他信息从在线用户缓存中获取
            Claim[] claims =
            {
                new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
                new Claim(ClaimTypes.Name, user.UserName)
            };
            TomNetOptions options = HttpContext.RequestServices.GetTomNetOptions();
            string token = JwtHelper.CreateToken(claims, options);

            return new AjaxResult("登录成功", AjaxResultType.Success, token);
        }
        [AllowAnonymous]
        [HttpPost]
        /// <summary>
        /// 注册
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public AjaxResult Register(RegisterDto dto)
        {
            Check.NotNull(dto, nameof(dto));

            if (!ModelState.IsValid)
            {
                return new AjaxResult("提交信息验证失败", AjaxResultType.Error);
            }

            var code = _cache.Get<string>(RedisKeyConst.RegisterCode + "_" + dto.UserName);
            if (code != dto.Code)
            {
                return new AjaxResult("验证码错误", AjaxResultType.Error);
            }

            if (_unitOfWork.DbContext.Queryable<UserLogin>().Any(m => m.UserName == dto.UserName))
            {
                return new AjaxResult("用户名已存在", AjaxResultType.Error);
            }
            dto.Password = HashHelper.GetMd5(dto.Password);
            UserLogin userLogin = new UserLogin
            {
                IsLocked = false,
                Password = dto.Password,
                UserName = dto.UserName
            };
            userLogin = _unitOfWork.DbContext.Insertable(userLogin).ExecuteReturnEntity();
            UserInfo userInfo = new UserInfo
            {
                Age = 0,
                CreateTime = 0,
                Email = "",
                IdNumber = "",
                MobilePhone = "",
                NickName = "",
                RealName = "",
                Sex = true,
                Telephone = "",
                UserId = userLogin.Id
            };
            _unitOfWork.DbContext.Insertable(userInfo).ExecuteCommand();

            return new AjaxResult("注册成功", AjaxResultType.Success);
        }
        [AllowAnonymous]
        [HttpPost]
        /// <summary>
        /// 注册验证码
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public AjaxResult RegisterCode(string UserName)
        {

            if (_unitOfWork.DbContext.Queryable<UserLogin>().Any(m => m.UserName == UserName))
            {
                return new AjaxResult("用户名已存在", AjaxResultType.Error);
            }
            var check = _cache.Get<string>(RedisKeyConst.PhoneMsgTime + "_" + UserName);
            if (check != null)
            {
                return new AjaxResult("请勿频繁获取手机验证码", AjaxResultType.Error);
            }

            Random random = new Random();
            var code = random.NextNumberString(5);

            //发送短信

            _cache.Set(RedisKeyConst.PhoneMsgTime + "_" + UserName, code, new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(15) });
            _cache.Set(RedisKeyConst.RegisterCode + "_" + UserName, code, new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(15) });
            return new AjaxResult("验证码已发送，测试 验证码：" + code, AjaxResultType.Success);
        }
        [AllowAnonymous]
        [HttpPost]
        /// <summary>
        /// 找回密码
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public AjaxResult FindPassWord(RegisterDto dto)
        {
            Check.NotNull(dto, nameof(dto));

            if (!ModelState.IsValid)
            {
                return new AjaxResult("提交信息验证失败", AjaxResultType.Error);
            }

            var code = _cache.Get<string>(RedisKeyConst.FindPassWord + "_" + dto.UserName);
            if (code != dto.Code)
            {
                return new AjaxResult("验证码错误", AjaxResultType.Error);
            }
            var userLogin = _unitOfWork.DbContext.Queryable<UserLogin>().Where(m => m.UserName == dto.UserName).First();
            if (userLogin == null)
            {
                return new AjaxResult("用户不存在", AjaxResultType.Error);
            }
            userLogin.Password = HashHelper.GetMd5(dto.Password);

            _unitOfWork.DbContext.Updateable(userLogin).ExecuteCommand();


            return new AjaxResult("密码修改成功", AjaxResultType.Success);
        }
        [AllowAnonymous]
        [HttpPost]
        /// <summary>
        /// 找回密码验证码
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public AjaxResult FindPassWordCode(string UserName)
        {

            if (!_unitOfWork.DbContext.Queryable<UserLogin>().Any(m => m.UserName == UserName))
            {
                return new AjaxResult("用户不已存在", AjaxResultType.Error);
            }
            var check = _cache.Get<string>(RedisKeyConst.PhoneMsgTime + "_" + UserName);
            if (check != null)
            {
                return new AjaxResult("请勿频繁获取手机验证码", AjaxResultType.Error);
            }

            Random random = new Random();
            var code = random.NextNumberString(5);

            //发送短信

            _cache.Set(RedisKeyConst.PhoneMsgTime + "_" + UserName, code, new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(15) });
            _cache.Set(RedisKeyConst.FindPassWord + "_" + UserName, code, new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(15) });
            return new AjaxResult("验证码已发送，测试 验证码：" + code, AjaxResultType.Success);
        }

        public AjaxResult TestApi()
        {
            var y = this.User.Identity.Name;
            return new AjaxResult("允许访问", AjaxResultType.Success, y);
        }

        [AllowAnonymous]
        public AjaxResult FreeApi(string value)
        {
            _cache.Set("aaa", value, new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(15)
            });
            VirtualCurrencyData virtualCurrencyData = new VirtualCurrencyData(_httpClientFactory, _cache);
            //virtualCurrencyData.aa();
            return new AjaxResult("允许访问", AjaxResultType.Success);
        }
        [AllowAnonymous]
        public AjaxResult FreeApi2()
        {
            var val = _cache.Get<string>("aaa");
            VirtualCurrencyData virtualCurrencyData = new VirtualCurrencyData(_httpClientFactory, _cache);
            var d = virtualCurrencyData.GetLineData("btc");
            var d1 = virtualCurrencyData.GetProfitData("btc");
            return new AjaxResult(val, AjaxResultType.Success, val);
        }
    }
}